﻿
namespace LS.Nc6.Web.Entry.Areas.Systems.Controllers
{
    /// <summary>
    /// 文件管理
    /// </summary>
    [Route("[area]/[controller]/[action]")]
    [Area("Systems")]
    [ApiDescriptionSettings("Default")]
    public class FilesController : BaseAdminController
    {
        #region FilesController
        private readonly ISysFileService _fileService;
        private readonly ICache _cache; 
        
        public FilesController(ISysFileService fileService, IOptions<CacheOptions> cacheOptions, Func<string, ISingleton, object> resolveNamed)
            : base(cacheOptions, resolveNamed)
        {
            _fileService = fileService;
            _cache = resolveNamed(cacheOptions.Value.CacheType.ToString(), default) as ICache;
        }
        #endregion
        #region 页面
        public ActionResult Index()
        {
            SysPower(SysMenuConstant.MENU_FILES_MANAGE, SysMenuConstant.FUN_SELECT, UserInfo.ID.ToString());
            return View();
        }
      
       
        #endregion

        #region  公共方法
       

        [HttpGet]
        public async Task<ResponseResultDataList> GetAllFiles()
        {
            string bizetype = RequestHelper.FilterParam(Request.Query["bizetype"]);
            string foname = RequestHelper.FilterParam(Request.Query["foname"]);
            var page = Request.Query["page"].ToString().GetQueryValueOrNull<int>(1);
            var limit = Request.Query["limit"].ToString().GetQueryValueOrNull<int>(20);
            string field = Request.Query["field"];
            string order = Request.Query["order"];

            var expable = Expressionable.Create<SysFileEntity>();
            expable.AndIF(!string.IsNullOrEmpty(bizetype), a => a.Bizetype == bizetype);
            expable.AndIF(!string.IsNullOrEmpty(foname), a => a.Foname == foname);
            var exp = expable.ToExpression();
            var strField = RequestHelper.FilterParam(field);
            var strOrder = RequestHelper.FilterParam(order);

            Expression<Func<SysFileEntity, object>> expressionOrder;
            if (string.IsNullOrEmpty(strField) || string.IsNullOrEmpty(strOrder))
            {
                expressionOrder = (a) => new { a.Id };
            }
            else
            {
                //实现字段排序
                expressionOrder = (a) => new { a.CreateDate };
            }
            var result =await _fileService.PageList(exp, page, limit, expressionOrder);
            return new ResponseResultDataList { code = ResponseHelper.SEUCCESSCODE, message = "请求成功", data = result.Items, count = result.TotalCount };
        }

        [HttpGet]
        public async Task<ResponseDataResult> CustomerFileList(string ids)
        {
            var result = await  _fileService.CustomerFileList(ids);
            return new ResponseDataResult { code = ResponseHelper.SEUCCESSCODE, message = "请求成功", data = result };
        }

        [HttpPost]
        public async Task<ResponseResult> DelFile(string ids)
        {
            var r = SysPower(SysMenuConstant.MENU_DICTIONARY_MANAGE, SysMenuConstant.FUN_DELETE, UserInfo.ID.ToString(), false);
            if (!r)
            {
                return ResponseHelper.MessageResult(ResponseHelper.PERMISSION_WSCQX);
            }
            int result =await _fileService.DeleteAsync(ids.ToString());
            return ResponseHelper.DeleteResult(result);
          
        }
        [HttpGet]
        public async Task<IActionResult> DownloadFile(long id)
        {
            var filemodel= await _fileService.GetByIdAsync(id);
            if (filemodel==null)
            {
              return ErrorCustomMsg("文件不存在");
            }
            string basePath = AppContext.BaseDirectory;
            var filePath = basePath+filemodel.Fpath;     //Path.Combine("upload", "BMP.rar");
           
            //要下载的文件地址，这个文件会被分成片段，通过循环逐步读取到ASP.NET Core中，然后发送给客户端浏览器
            var fileName = filemodel.Foname;  
            int bufferSize = 1024;//这就是ASP.NET Core循环读取下载文件的缓存大小，这里我们设置为了1024字节，也就是说ASP.NET Core每次会从下载文件中读取1024字节的内容到服务器内存中，然后发送到客户端浏览器，这样避免了一次将整个下载文件都加载到服务器内存中，导致服务器崩溃
            if (filemodel.Ftype.Contains("png"))
            {
                Response.ContentType = "image/png";
            }
            else if (filemodel.Ftype.Contains("jpg") || filemodel.Ftype.Contains("jpeg"))
            {
                Response.ContentType = "image/jpg";
            }
            else if(filemodel.Ftype.Contains("zip") || filemodel.Ftype.Contains("rar"))
            {
                Response.ContentType = "application/zip";
            }
            else if (filemodel.Ftype.Contains("zip") || filemodel.Ftype.Contains("rar"))
            {
                Response.ContentType = "application/zip";
            }else if (filemodel.Ftype.Contains("xls") )
            {
                Response.ContentType = "application/vnd.ms-excel";
            }
            else if (filemodel.Ftype.Contains("xlsx"))
            {
                Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";   
            }
            else if (filemodel.Ftype.Contains("doc"))
            {
                Response.ContentType = "application/msword";
            }
            else if (filemodel.Ftype.Contains("docx"))
            {
                Response.ContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
            }
            else if (filemodel.Ftype.Contains("pdf"))
            {
                Response.ContentType = "application/pdf";
            }
            else
            {
                Response.ContentType = "application/octet-stream";
            }

            var contentDisposition = "attachment;" + "filename=" + HttpUtility.UrlEncode(fileName);//在Response的Header中设置下载文件的文件名，这样客户端浏览器才能正确显示下载的文件名，注意这里要用HttpUtility.UrlEncode编码文件名，否则有些浏览器可能会显示乱码文件名
            Response.Headers.Add("Content-Disposition", new string[] { contentDisposition });
            using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
            {
                using (Response.Body)
                {
                    long contentLength = fs.Length;
                    Response.ContentLength = contentLength;

                    byte[] buffer;
                    long hasRead = 0;

                    while (hasRead < contentLength)
                    {
                        if (HttpContext.RequestAborted.IsCancellationRequested)
                        {
                            break;
                        }

                        buffer = new byte[bufferSize];
                        int currentRead = fs.Read(buffer, 0, bufferSize);
                        await Response.Body.WriteAsync(buffer, 0, currentRead);
                        await Response.Body.FlushAsync();
                        hasRead += currentRead;
                    }
                }
            }
        
            return new EmptyResult();
        }
        #endregion


        #region 私有方法

        #endregion
    }
}